package edu.dayu.demo1;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class ByteBufferTest {
    public static void main(String[] args) {

//        try {
//            FileChannel channel = new FileInputStream("C:\\Users\\86134\\Desktop\\data.txt").getChannel();
//            // 准备缓冲区：开辟一块 10 字节的堆内存空间
//            ByteBuffer byteBuffer = ByteBuffer.allocate(10);
//            while (true){
//                // 从 channel 读取数据，写入 buffer
//                int len = channel.read(byteBuffer);
//                System.out.println(String.format("已读取 %d 字节",len));
//                if (len == -1){
//                    break;
//                }
//                //  切换 buffer 读模式
//                byteBuffer.flip();
//                // 在 buffer 中是否还有剩余的内容
//                while (byteBuffer.hasRemaining()){
//                    byte b = byteBuffer.get();
//                    System.out.println(String.format("当前读取的字节为 %c",(char)b));
//                }
//                // 把 position 置为 0
//                byteBuffer.rewind();
//                while (byteBuffer.hasRemaining()){
//                    byte b = byteBuffer.get();
//                    System.out.println(String.format("当前读取的字节为 %c",(char)b));
//                }
//
//                // 切换 buffer 写模式
//                byteBuffer.clear();
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
            demo();
    }

    /**
     * 分散读
     */
    public static void splitRead(){
        try {
            FileChannel channel = new FileInputStream("C:\\Users\\86134\\Desktop\\data.txt").getChannel();
            ByteBuffer b1 = ByteBuffer.allocate(3);
            ByteBuffer b2 = ByteBuffer.allocate(4);
            ByteBuffer b3 = ByteBuffer.allocate(3);
            while (true) {
                long len = channel.read(new ByteBuffer[]{b1, b2, b3});
                System.out.println(String.format("已读取 %d 字节",len));
                if (len == -1){
                    break;
                }
                print(b1);
                print(b2);
                print(b3);
                channel.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void print(ByteBuffer buffer){
        buffer.flip();
        while (buffer.hasRemaining()){
            byte b = buffer.get();
            System.out.println(String.format("当前读取的字节为 %c",(char)b));
        }
        buffer.clear();
    }


    /**
     * 案例 网络黏包、半包问题
     */
    public static void demo(){
        ByteBuffer buffer = ByteBuffer.allocate(256);
        //黏包情况：
        buffer.put("I am changlu!\nhello,xiaoli\nhi".getBytes());
        handle(buffer);
        //半包情况：
        buffer.put(",are you ok?\n".getBytes());
        handle(buffer);
    }

    /**
     * 处理
     */
    public static void handle(ByteBuffer buffer){
        buffer.flip();
        for (int i =0; i< buffer.limit();i++){
            if (buffer.get(i) == '\n'){
                int readLen = i - buffer.position() +1;
                ByteBuffer buffer1 = ByteBuffer.allocate(readLen);
                for (int j = 0; j < readLen; j++) {
                    buffer1.put(buffer.get());
                }
                prints(buffer1);

            }
        }
        // 保留未读取的内容
        buffer.compact();
    }

    /**
     * 输出
     */
    public static void prints(ByteBuffer b){
        b.flip();
        StringBuffer s = new StringBuffer();
        while (b.hasRemaining()){
            s.append((char) b.get());
        }
        b.clear();
        System.out.println(s);
    }
}
